package joodle.tools;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;

import joodle.domain.Canvas;
import joodle.domain.Point;

/**
 * RectangularSelectionTool is responsible for coordinating the selection process by the user. 
 * RectangularSelectionTool class provides rectangular selection in which user draws a rectangle on 
 * canvas after which all the shapes contained in the selection rectangle are marked as selected.
 * <p><center>
 * <img src="http://ug.bcc.bilkent.edu.tr/~m_ozdal/Site/Reports_files/design_files/image010.jpg" />
 * </center></p>
 */
public class RectangularSelectionTool implements Tool {
	private Point p1;
	private Point p2;
	private static RectangularSelectionTool instance = new RectangularSelectionTool();

	private RectangularSelectionTool() {
		p1 = p2 = null;
	}
		
	public static RectangularSelectionTool instance() {
		return instance;
	}

	/**
	 * Draws a rectangle figure as an indicator of RectangularSelectionTool
	 * @see Tool#drawInterim(Graphics)
	 */
	@Override
	public void drawInterim(Graphics g) {
		if(p1 == null || p2 == null)
			return;
		
		Graphics2D g2 = (Graphics2D) g.create();

		g2.setColor(TransformationTool.INTERIM_COLOR);
		g2.setStroke(TransformationTool.INTERIM_STROKE);

		Point pmin = Point.minPoint(p1, p2);
		Point pmax = Point.maxPoint(p1, p2);
		
		g2.draw(new java.awt.geom.Rectangle2D.Float(
				pmin.getX(), pmin.getY(),
				pmax.getX() - pmin.getX(),
				pmax.getY() - pmin.getY()));
		g2.dispose();
	}

	/**
	 * Invoked when the mouse cursor has been moved onto a component. Slides the end point of the
	 * selection rectangle according to moved point 
	 * @see Tool#handleMove(Point, boolean, boolean)
	 */
	@Override
	public void handleMove(Point p, boolean ctrl, boolean lb) {
		if(p1 != null && lb)
			p2 = p;
	}

	/**
	 * Invoked when the mouse button has been clicked (pressed and released) on a component.
	 * @see Tool#handlePress(Point, boolean)
	 */
	@Override
	public void handlePress(Point p, boolean ctrl) {
		p1 = p;
		Canvas.instance().clearSelection();
	}

	/**
	 * Invoked when a mouse button has been released on a component. 
	 * @see Tool#handleRelease(Point, boolean)
	 */
	@Override
	public void handleRelease(Point p, boolean ctrl) {
		Canvas.instance().setSelection(
				Point.minPoint(p1, p),
				Point.maxPoint(p1, p),
				true);
		p1 = p2 = null;
	}

	/**
	 * Invoked when escape key has been pressed.
	 * @see Tool#handleKeyPress(int)
	 */
	@Override
	public void handleKeyPress(int c) {
		if(c == KeyEvent.VK_ESCAPE) {
			Canvas.instance().clearSelection();
		}
	}

	/**
	 * @see Tool#handleKeyType(char)
	 */
	@Override
	public void handleKeyType(char c) {
	}

}
